package cn.amossun.starter.event.handler;

import cn.amossun.starter.event.common.Constants;
import cn.amossun.starter.event.enums.DurabilityEnum;
import cn.amossun.starter.event.enums.ExchangeTypeEnum;
import cn.amossun.starter.event.property.EventContext;
import cn.amossun.starter.event.property.EventExchangeContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.InitializingBean;

@Slf4j
public class EventExchangeInitializer implements InitializingBean {

    private EventContext eventContext;

    private RabbitAdmin rabbitAdmin;

    public EventExchangeInitializer(EventContext eventContext, RabbitAdmin rabbitAdmin) {
        this.eventContext = eventContext;
        this.rabbitAdmin = rabbitAdmin;
        addSystemExchanges();
    }

    private void addSystemExchanges() {
        eventContext.getExchangeContexts().add(new EventExchangeContext(Constants.EVENT_TOPIC_EXCHANGE, ExchangeTypeEnum.TOPIC, DurabilityEnum.DURABLE, false));
        eventContext.getExchangeContexts().add(new EventExchangeContext(Constants.EVENT_HEADER_EXCHANGE, ExchangeTypeEnum.HEADERS, DurabilityEnum.DURABLE, false));
        eventContext.getExchangeContexts().add(new EventExchangeContext(Constants.EVENT_DEAD_EXCHANGE, ExchangeTypeEnum.DIRECT, DurabilityEnum.DURABLE, false));
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        initialize();
    }

    void initialize() {
        eventContext.getExchangeContexts().stream().forEach(exchangeContext -> {
            Exchange exchange = null;
            switch (exchangeContext.getType().getTypeValue()) {
                case ExchangeTypes.TOPIC:
                    exchange = new TopicExchange(exchangeContext.getExchangeName(), exchangeContext.isDurable(), exchangeContext.isAutoDelete(), exchangeContext.getArgumentsMap());
                    break;
                case ExchangeTypes.DIRECT:
                    exchange = new DirectExchange(exchangeContext.getExchangeName(), exchangeContext.isDurable(), exchangeContext.isAutoDelete(), exchangeContext.getArgumentsMap());
                    break;
                case ExchangeTypes.HEADERS:
                    exchange = new HeadersExchange(exchangeContext.getExchangeName(), exchangeContext.isDurable(), exchangeContext.isAutoDelete(), exchangeContext.getArgumentsMap());
                    break;
                case ExchangeTypes.FANOUT:
                    exchange = new FanoutExchange(exchangeContext.getExchangeName(), exchangeContext.isDurable(), exchangeContext.isAutoDelete(), exchangeContext.getArgumentsMap());
                    break;
                case ExchangeTypes.SYSTEM:
                    exchange = new CustomExchange(exchangeContext.getExchangeName(), ExchangeTypes.SYSTEM, exchangeContext.isDurable(), exchangeContext.isAutoDelete(), exchangeContext.getArgumentsMap());
                    break;
            }
            rabbitAdmin.declareExchange(exchange);
            exchangeContext.setExchange(exchange);
        });
    }
}
